// lib/services/network/socket_client.dart
import 'dart:io';
import 'dart:convert';
import 'dart:async';
import 'package:get/get.dart';

class SocketClient extends GetxService {
  Socket? _socket;
  Socket? _socketLogin;
  IOSink? _dout;
  IOSink? _doutLogin;
  Stream<List<int>>? _broadcastStream;
  Stream<List<int>>? _broadcastStreamLogin;

  final String _ipAddress = "www.baostock.com";
  final int _socketPort = 10030;

  // 添加标志位跟踪连接状态
  bool _isConnecting = false;
  bool _isLoginConnecting = false;

  // 添加缓冲区来处理不完整的UTF-8序列
  List<int> _buffer = [];

  @override
  void onInit() {
    super.onInit();
    _initConnect();
  }

  Future<void> _initConnect() async {
    if (_isConnecting) return;
    _isConnecting = true;

    try {
      _socket = await Socket.connect(_ipAddress, _socketPort, timeout: const Duration(seconds: 10));
      _socket!.setOption(SocketOption.tcpNoDelay, true);
      _dout = _socket!;
      _broadcastStream = _socket!.asBroadcastStream();
      print("connect server successful");
    } catch (e) {
      print("connect server failed: $e");
    } finally {
      _isConnecting = false;
    }
  }

  Future<void> _initLoginConnect() async {
    if (_isLoginConnecting) return;
    _isLoginConnecting = true;

    try {
      _socketLogin = await Socket.connect(_ipAddress, _socketPort, timeout: const Duration(seconds: 10));
      _socketLogin!.setOption(SocketOption.tcpNoDelay, true);
      _doutLogin = _socketLogin!;
      _broadcastStreamLogin = _socketLogin!.asBroadcastStream();
      print("connect login server successful");
    } catch (e) {
      print("connect login server failed: $e");
    } finally {
      _isLoginConnecting = false;
    }
  }

  Future<void> sendMessage(String message) async {
    if (_dout == null || message.isEmpty) {
      print("The message to be sent is empty or have no connect");
      // 尝试重新连接
      await _initConnect();
      if (_dout == null) {
        print("Failed to reconnect");
        return;
      }
    }

    try {
      message = "$message\n";
      _dout!.write(message);
      await _dout!.flush();
      print("send message successful");
    } catch (e) {
      print("send message error: $e");
    }
  }

  Future<void> sendMessageLogin(String message) async {
    if (_doutLogin == null) {
      await _initLoginConnect();
      if (_doutLogin == null) {
        print("stock_client71:Failed to connect for login");
        return;
      }
    }

    try {
      message = "$message\n";
      _doutLogin!.write(message);
      await _doutLogin!.flush();
      print("send login message successful");
    } catch (e) {
      print("send login message error: $e");
    }
  }

  Future<String> receiveMessageLogin() async {
    if (_broadcastStreamLogin == null) {
      await _initLoginConnect();
      if (_broadcastStreamLogin == null) {
        return "";
      }
    }

    try {
      final completer = Completer<String>();
      var message = "";
      StreamSubscription<List<int>>? subscription;

      subscription = _broadcastStreamLogin!.listen(
              (data) {
            try {
              // 使用更安全的UTF-8解码方式
              final received = _safeUtf8Decode(data);
              message += received;
              print("接收到登录响应：$received");

              // 检查是否收到完整的消息
              if (message.contains('\n')) {
                if (!completer.isCompleted) {
                  completer.complete(message);
                }
                subscription?.cancel();
              }
            } catch (e) {
              print("解码登录响应错误: $e");
            }
          },
          onError: (e) {
            print("receive login message error: $e");
            if (!completer.isCompleted) {
              completer.complete("");
            }
          },
          onDone: () {
            if (!completer.isCompleted) {
              completer.complete(message);
            }
          },
          cancelOnError: true
      );

      // 设置超时
      Future.delayed(Duration(seconds: 10), () {
        if (!completer.isCompleted) {
          subscription?.cancel();
          completer.complete(message);
        }
      });

      return await completer.future;
    } catch (e) {
      print("receive login message error: $e");
      return "";
    }
  }

  Future<String> receiveMessage() async {
    if (_broadcastStream == null) {
      await _initConnect();
      if (_broadcastStream == null) {
        return "";
      }
    }

    try {
      final completer = Completer<String>();
      var message = "";
      StreamSubscription<List<int>>? subscription;

      subscription = _broadcastStream!.listen(
              (data) {
            try {
              // 使用更安全的UTF-8解码方式
              final received = _safeUtf8Decode(data);
              message += received;
              print("接收到：$received");

              // 检查是否收到完整的消息
              if (message.contains('\n')) {
                if (!completer.isCompleted) {
                  completer.complete(message);
                }
                subscription?.cancel();
              }
            } catch (e) {
              print("解码消息错误: $e");
            }
          },
          onError: (e) {
            print("receive message error: $e");
            if (!completer.isCompleted) {
              completer.complete("");
            }
          },
          onDone: () {
            if (!completer.isCompleted) {
              completer.complete(message);
            }
          },
          cancelOnError: true
      );

      // 设置超时
      Future.delayed(Duration(seconds: 10), () {
        if (!completer.isCompleted) {
          subscription?.cancel();
          completer.complete(message);
        }
      });

      return await completer.future;
    } catch (e) {
      print("receive message error: $e");
      return "";
    }
  }

  Future<String> receiveMessage2() async {
    if (_broadcastStream == null) {
      await _initConnect();
      if (_broadcastStream == null) {
        return "";
      }
    }

    try {
      final completer = Completer<String>();
      var message = "";
      StreamSubscription<List<int>>? subscription;

      subscription = _broadcastStream!.listen(
              (data) {
            try {
              // 使用更安全的UTF-8解码方式
              final received = _safeUtf8Decode(data);
              message += received;
              print("接收到了：$received");

              // 检查是否收到完整的消息（以特定结束标记）
              if (message.endsWith("TA[]]>\n") || message.endsWith("\n")) {
                if (!completer.isCompleted) {
                  completer.complete(message);
                }
                subscription?.cancel();
              }
            } catch (e) {
              print("解码消息2错误: $e");
            }
          },
          onError: (e) {
            print("receive message2 error: $e");
            if (!completer.isCompleted) {
              completer.complete("");
            }
          },
          onDone: () {
            if (!completer.isCompleted) {
              completer.complete(message);
            }
          },
          cancelOnError: true
      );

      // 设置超时
      Future.delayed(Duration(seconds: 30), () {
        if (!completer.isCompleted) {
          subscription?.cancel();
          completer.complete(message);
        }
      });

      return await completer.future;
    } catch (e) {
      print("receive message2 error: $e");
      return "";
    }
  }

  // 安全的UTF-8解码方法，处理不完整的字节序列
  String _safeUtf8Decode(List<int> bytes) {
    try {
      // 先将新数据添加到缓冲区
      _buffer.addAll(bytes);

      // 尝试解码整个缓冲区
      final result = utf8.decode(_buffer, allowMalformed: false);

      // 如果成功解码，清空缓冲区
      _buffer.clear();
      return result;
    } catch (e) {
      // 如果解码失败，可能是因为有不完整的UTF-8序列
      // 保留缓冲区中的数据，等待下一次数据到达
      print("UTF-8解码失败，保留缓冲区数据: $e");
      return "";
    }
  }

  void closeConnect() {
    try {
      _dout?.close();
      _socket?.close();
      _doutLogin?.close();
      _socketLogin?.close();
      _buffer.clear(); // 清空缓冲区
      print("关闭连接");
    } catch (e) {
      print("close connect error: $e");
    }
  }

  @override
  void onClose() {
    closeConnect();
    super.onClose();
  }
}